package cn.jtfadmin.base.lang.common.utils;


import cn.jtfadmin.base.lang.config.ApplicationHolder;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * json 工具, json 转对象/对象转json
 * @author jtf
 * @since 0.0.1
 */
public class JsonUtils {


    private static ObjectMapper objectMapper;

    /**
     * 将字符串转换为class对象类
     *
     * @param source 字符串
     * @param clazz  转换成为的对象
     * @param <T>    对象泛型
     * @return 对象
     */
    public static <T> T transfer(String source, Class<T> clazz) {
        try {
            return getObjectMapper().readValue(source, clazz);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将字符串转换为数组对象
     *
     * @param source 字符串
     * @param clazz  转换的对象类型
     * @param <T>    对象类型
     * @return 数组
     */
    public static <T> T[] constructArrayType(String source, Class<T> clazz) {
        try {
            TypeFactory typeFactory = TypeFactory.defaultInstance();
            return getObjectMapper().readValue(source,
                    typeFactory.constructArrayType(clazz));
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 构造list
     *
     * @param source
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> List<T> constuctListType(InputStream source, Class<T> clazz) {
        try {
            ObjectMapper objectMapper = getObjectMapper();
            TypeFactory typeFactory = objectMapper.getTypeFactory();
            return objectMapper.readValue(source,
                    typeFactory.constructCollectionLikeType(ArrayList.class, clazz));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 构造list
     *
     * @param source
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> List<T> constuctListType(String source, Class<T> clazz) {
        try {
            ObjectMapper objectMapper = getObjectMapper();
            TypeFactory typeFactory = objectMapper.getTypeFactory();
            return objectMapper.readValue(source,
                    typeFactory.constructCollectionLikeType(ArrayList.class, clazz));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static ObjectMapper getObjectMapper() {
        try {
            ObjectMapper bean = ApplicationHolder.getApplicationContext().getBean(ObjectMapper.class);
            return bean;
        } catch (Exception ex) {
            if (objectMapper == null) {
                synchronized (JsonUtils.class) {
                    if (objectMapper == null) {
                        objectMapper = new ObjectMapper();
                    }
                }
            }
            return objectMapper;
        }

    }

    /**
     * 将对象转换为json字符串
     *
     * @param object 对象
     * @return
     */
    public static String toJsonStr(Object object) {
        try {
            return getObjectMapper().writeValueAsString(object);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}
